package core.commit.standard;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.fastjson.JSON;

import core.commit.mm_submit;
import core.commit.param_constructor.mm_commit_param_constructor;
import core.commit.param_constructor.mm_standard_commit_param_constructor;
import core.net.mm_http_client;
import core.query.mm_query_result;
import core.reactor.mm_reactor;
import log.mm_logger;
import utils.mm_parse;
import utils.mm_thread;

/**
 * 标准提交
 * @author dongyazhuo
 */
public class mm_standard_submit implements mm_submit {

	private String TAG = mm_standard_submit.class.getSimpleName() + " : ";

	private mm_reactor _mm_reactor;
	private mm_http_client _mm_http_client;
	private Map<String, Object> token;// 提交订单的一些token信息
	private Integer ifShowPassCodeTime = null;// 订单提交等待时间
	private boolean ifShowPassCode = false;// 是否需要验证码

	public mm_standard_submit(mm_reactor _mm_reactor) {
		super();
		this._mm_reactor = _mm_reactor;
		this._mm_http_client = _mm_reactor._mm_http_client;
		TAG += _mm_reactor._mm_config.getSet().getAccount_12306().getUser() + " : ";
	}

	/**
	 * 提交车次 预定的请求参数，注意参数顺序 注意这里为了防止secretStr被urllib.parse过度编码，在这里进行一次解码
	 * 否则调用HttpTester类的post方法将会将secretStr编码成为无效码,造成提交预定请求失败 :param secretStr: 提交车次加密
	 */
	@Override
	public void submit(HashMap<String, Object> request_parm, mm_query_result _mm_query_result) {
		boolean reserve = reserve(request_parm, _mm_query_result);// 预定
		mm_logger.w(TAG + "reserve ：" + reserve);
		if (reserve) {
			token = get_token();// 获取token
			if (null != token && null != token.get("token")) {
				boolean check_order = check_order(request_parm, _mm_query_result);// 检查订单是否提交成功
				mm_logger.w(TAG + "check_order ：" + check_order);
				if (check_order) {
					boolean queue = queue(_mm_query_result);// 排队
					mm_logger.w(TAG + "queue ：" + queue);
					if (queue) {
						confirm(_mm_query_result);// 确认购买!!!
					}
				}
			}
		}
	}

	/**
	 * 预定
	 * @param request_parm
	 * @param _mm_query_result
	 * @return
	 */
	private boolean reserve(HashMap<String, Object> request_parm, mm_query_result _mm_query_result) {
		Map<String, Object> url = _mm_reactor._mm_config.getUrl_config().get("submit_station_url");
		Map<String, Object> param = mm_standard_commit_param_constructor.submit_data_par(_mm_query_result);
		HashMap<String, Object> result = (HashMap<String, Object>) _mm_http_client.send(url, param);
		if (null != result && null != result.get("data")) {
			return "N".equals(result.get("data").toString());
		} else if (null != result && null != result.get("messages")) {
			ArrayList list = JSON.parseObject(result.get("messages").toString(), ArrayList.class);
			mm_logger.w(TAG + list.get(0));
		}
		return false;
	}

	/**
	 * 获取订单提交的token，及其他的一些信息
	 * @return
	 */
	private Map<String, Object> get_token() {
		Map<String, Object> r = new HashMap<>();

		Map<String, Object> url = _mm_reactor._mm_config.getUrl_config().get("initdc_url");
		Object send = _mm_http_client.send(url, new HashMap<>());
		String result = send.toString();
		String regex = "var globalRepeatSubmitToken = '(\\S+)'";
		Pattern p = Pattern.compile(regex);
		Matcher matcher = p.matcher(result);
		if (matcher.find()) {
			r.put("token", matcher.group(0).replaceAll(" ", "").split("'")[1]);
		}
		String ticketInfoForPassengerForm = search(result, "ticketInfoForPassengerForm=");
		String orderRequestDTO = search(result, "orderRequestDTO=");
		if (null != ticketInfoForPassengerForm && null != orderRequestDTO) {
			r.put("ticketInfoForPassengerForm", JSON.parseObject(ticketInfoForPassengerForm, HashMap.class));
			r.put("order_request_params", JSON.parseObject(orderRequestDTO, HashMap.class));
		}
		return r;
	}

	private String search(String content, String search) {
		int start = content.indexOf(search);
		if (-1 == start) {
			return null;
		}
		String substring = content.substring(start);
		int indexOf = substring.indexOf(";");
		String substring2 = substring.substring(0, indexOf);
		return substring2.substring(search.length(), substring2.length());
	}

	/**
	 * 检查订单是否提交成功
	 * @param _mm_query_result
	 * @return
	 */
	private boolean check_order(HashMap<String, Object> request_parm, mm_query_result _mm_query_result) {
		Map<String, Object> url = _mm_reactor._mm_config.getUrl_config().get("checkOrderInfoUrl");
		Map<String, Object> param = mm_standard_commit_param_constructor.check_order_data_apr(request_parm, token,
				_mm_query_result);
		HashMap<String, Object> result = (HashMap<String, Object>) _mm_http_client.send(url, param);
		if (null != result && null != result.get("data")) {
			HashMap<String, Object> data = JSON.parseObject(result.get("data").toString(), HashMap.class);
			if (null != data.get("submitStatus")) {
				mm_logger.i(TAG + "车票提交通过，正在尝试排队");
				if (null != data.get("ifShowPassCodeTime")) {
					ifShowPassCodeTime = Integer.parseInt(data.get("ifShowPassCodeTime").toString());
				}
				if (null != data.get("ifShowPassCode")) {
					ifShowPassCode = "Y".equals(data.get("ifShowPassCode").toString());
				}
				if (Boolean.parseBoolean(data.get("submitStatus").toString())) {
					ifShowPassCode = false;
				}
				return true;
			}
		} else if (null != result) {
			mm_logger.w(TAG + result);
			return false;
		}
		return false;
	}

	/**
	 * 排队
	 * @param _mm_query_result
	 * @return
	 */
	private boolean queue(mm_query_result _mm_query_result) {
		Map<String, Object> url = _mm_reactor._mm_config.getUrl_config().get("getQueueCountUrl");
		Map<String, Object> _data_par = mm_standard_commit_param_constructor.query_queue_count_data_par(_mm_query_result, token);
		HashMap<String, Object> result = (HashMap<String, Object>) _mm_http_client.send(url, _data_par);
		if (null != result && null != result.get("status") && mm_parse.parse_bool(result.get("status"))) {
			if (mm_parse.parse_bool(result.get("status"))) {
				HashMap<String, Object> data = JSON.parseObject(result.get("data").toString(), HashMap.class);
				if (null != data.get("countT")) {
					String[] split = data.get("ticket").toString().split(",");
					int count = 0;
					for (String string : split) {
						count += Integer.parseInt(string);
					}
					mm_logger.i(TAG + "排队成功, 当前余票还剩余: {" + count + "} 张。" + "排队位置：" + data.get("countT"));
					return true;
				} else {
					mm_logger.w(TAG + "排队发现未知错误{" + result + "}，将此列车 {" + _mm_query_result.train_no + "}加入小黑屋");
					int ticket_black_list_time = _mm_reactor._mm_config.getTicket_black_list_time();
					_mm_reactor._mm_cache.set(_mm_query_result.train_no, ticket_black_list_time * 60 * 1000);
				}
			}
		} else if (null != result && null != result.get("messages")) {
			String format = String.format("排队异常，错误信息：{%s}, 将此列车 {%s}加入小黑屋", result.get("messages"), _mm_query_result.train_no);
			mm_logger.w(TAG + format);
			int ticket_black_list_time = _mm_reactor._mm_config.getTicket_black_list_time();
			_mm_reactor._mm_cache.set(_mm_query_result.train_no, ticket_black_list_time * 60 * 1000);
		} else if (null != result && null != result.get("validateMessages")) {
			String format = String.format("排队异常，错误信息：{%s}, 将此列车 {%s}加入小黑屋", result.get("validateMessages"),
					_mm_query_result.train_no);
			mm_logger.w(TAG + format);
			int ticket_black_list_time = _mm_reactor._mm_config.getTicket_black_list_time();
			_mm_reactor._mm_cache.set(_mm_query_result.train_no, ticket_black_list_time * 60 * 1000);
		} else {
			mm_logger.e(TAG + "未知错误" + result);
		}
		return false;
	}

	/**
	 * 确认
	 * @param _mm_query_result
	 * @param ifShowPassCodeTime
	 */
	private void confirm(mm_query_result _mm_query_result) {
		HashMap<String, Object> assenger_result = mm_commit_param_constructor.commit_data_par(_mm_query_result, _mm_reactor);
		Map<String, Object> parm = mm_standard_commit_param_constructor.submit_confirm_data_par(_mm_query_result, assenger_result,
				token);
		Map<String, Object> url = _mm_reactor._mm_config.getUrl_config().get("checkQueueOrderUrl");
		mm_thread.sleep(ifShowPassCodeTime + 0L);
		HashMap<String, Object> result = (HashMap<String, Object>) _mm_http_client.send(url, parm);
		if (null != result && null != result.get("status") && mm_parse.parse_bool(result.get("status"))) {
			HashMap<String, Object> data = JSON.parseObject(result.get("data").toString(), HashMap.class);
			if (null != data.get("submitStatus")) {
				if (mm_parse.parse_bool(data.get("submitStatus"))) {
					// sendQueryOrderWaitTime//排队获取订单等待信息,每隔3秒请求一次，最高请求次数为20次！
					_mm_reactor._mm_query_order_complete.sendQueryOrderWaitTime();
				}
			}
		}
		mm_logger.w(TAG + "订单提交失败。信息: " + result);
	}

}
